// Copyright (c) 2022 CHANGLEI. All rights reserved.

import 'package:aircraft_war/bloc/game_alive_cubit.dart';
import 'package:aircraft_war/bloc/game_bullet_cubit.dart';
import 'package:aircraft_war/bloc/game_firepower_cubit.dart';
import 'package:aircraft_war/bloc/game_score_cubit.dart';
import 'package:aircraft_war/bloc/game_state_cubit.dart';
import 'package:aircraft_war/commons/constants.dart';
import 'package:aircraft_war/components/camera.dart';
import 'package:aircraft_war/components/game_background.dart';
import 'package:aircraft_war/components/game_overlay.dart';
import 'package:aircraft_war/components/game_scene.dart';
import 'package:aircraft_war/generated/assets.dart';
import 'package:flame/components.dart';
import 'package:flame/experimental.dart';
import 'package:flame/flame.dart';
import 'package:flame/game.dart';
import 'package:flame_bloc/flame_bloc.dart';
import 'package:flutter/cupertino.dart' as cupertino;

const _backgroundColor = cupertino.Color(0xFFBCC1C2);

/// Created by changlei on 2022/5/17.
///
/// 游戏主程序
class MainGame extends FlameGame with HasDraggables, HasTappables, HasCollisionDetection {
  /// 游戏主程序
  MainGame(this.stateCubit);

  /// 状态管理
  final GameStateCubit stateCubit;

  /// 分数
  final scoreCubit = GameScoreCubit();

  /// 生命
  final aliveCubit = GameAliveCubit();

  /// 火力
  final firepowerCubit = GameFirepowerCubit();

  /// 增强子弹
  final bulletCubit = GameBulletCubit();

  @override
  bool get debugMode => isDebug;

  /// 是否正在运行
  bool get isRunning => stateCubit.isRunning;

  @override
  cupertino.Color backgroundColor() {
    return _backgroundColor;
  }

  @override
  Future<void> onLoad() async {
    await _loadImages();

    final world = World();
    await world.add(GameBackground());
    await world.add(GameScene());
    await world.add(GameOverlay());
    await add(FlameMultiBlocProvider(
      providers: [
        FlameBlocProvider<GameStateCubit, GameState>(
          create: () => stateCubit,
        ),
        FlameBlocProvider<GameScoreCubit, int>(
          create: () => scoreCubit,
        ),
        FlameBlocProvider<GameAliveCubit, int>(
          create: () => aliveCubit,
        ),
        FlameBlocProvider<GameFirepowerCubit, int>(
          create: () => firepowerCubit,
        ),
        FlameBlocProvider<GameBulletCubit, int>(
          create: () => bulletCubit,
        ),
      ],
      children: [
        world,
      ],
    ));

    final camera = MainCamera(world: world);
    camera.viewfinder.anchor = Anchor.topLeft;
    await add(camera);

    stateCubit.pending();
  }

  static Future<void> _loadImages() {
    return Future.wait<void>(<Future<void>>[
      Flame.images.load(Images.bomb),
      Flame.images.load(Images.resume_pressed),
      Flame.images.load(Images.me_destroy_3),
      Flame.images.load(Images.bomb_supply),
      Flame.images.load(Images.me_destroy_2),
      Flame.images.load(Images.bullet_supply),
      Flame.images.load(Images.enemy3_hit),
      Flame.images.load(Images.life),
      Flame.images.load(Images.enemy1_down4),
      Flame.images.load(Images.me_destroy_1),
      Flame.images.load(Images.enemy2_hit),
      Flame.images.load(Images.enemy1_down1),
      Flame.images.load(Images.me_destroy_4),
      Flame.images.load(Images.bullet2),
      Flame.images.load(Images.enemy1_down3),
      Flame.images.load(Images.enemy1_down2),
      Flame.images.load(Images.bullet1),
      Flame.images.load(Images.background),
      Flame.images.load(Images.enemy3_n2),
      Flame.images.load(Images.pause_pressed),
      Flame.images.load(Images.again),
      Flame.images.load(Images.enemy3_n1),
      Flame.images.load(Images.enemy2_down4),
      Flame.images.load(Images.enemy2_down1),
      Flame.images.load(Images.gameover),
      Flame.images.load(Images.enemy2_down2),
      Flame.images.load(Images.enemy2_down3),
      Flame.images.load(Images.pause_nor),
      Flame.images.load(Images.me2),
      Flame.images.load(Images.enemy1),
      Flame.images.load(Images.enemy3_down6),
      Flame.images.load(Images.me1),
      Flame.images.load(Images.enemy3_down4),
      Flame.images.load(Images.enemy2),
      Flame.images.load(Images.enemy3_down5),
      Flame.images.load(Images.enemy3_down1),
      Flame.images.load(Images.resume_nor),
      Flame.images.load(Images.enemy3_down2),
      Flame.images.load(Images.enemy3_down3),
      Flame.images.load(Images.shoot_copyright),
    ]);
  }
}
